﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _19_Composite
{
    class Program
    {
        /*
         组合模式(Composite)：将对象组合成数形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个
         对象和组合对象的使用具有一致性。

          透明方式：在Component 中声明所有用来管理子对象的方法，其中包括Add、Remove等。 这样实现Component
          接口的所有子类都具备了Add Remove。这样做的好处就是叶节点对于外界没有区别，他们具备完全一致的行为
          接口

        安全方式：在Component接口中不去声明Add 和 Remove方法，那么子类的Leaf也就不需要去实现它，而是在
        Composite 声明所有用来管理子类对象的方法，这样做就不会出现刚才提到的问题，不过由于不够透明，所以
        树叶和树枝类将不具有相同的接口，客户端的调用需要做相应的判断，带来了不变
         
        当需求中是体现部分与整体层次的结构时，你希望用户可以忽略组合对象与单个对象的不用，统一的使用组合
        结构中的所有对象时，可以考虑使用组合模式。

            组合模式定义包含了基本对象和组合对象类的层次结构。基本对象可以被组合成更复杂的对象，这个组合对象
            有可以被组合，这样不断的递归下去，客户代码中，任何用到基本对象的地方都可以使用组合对象。
            用户不用关心到底是处理一个叶节点还是处理一个组合组件，不用为定义组合而写一些判断
         */
        static void Main(string[] args)
        {
            Composite root = new Composite("Root");
            root.Add(new Leaf("Leaf A"));
            root.Add(new Leaf("Leaf B"));

            Composite comp = new Composite("Composite X");
            comp.Add(new Leaf("Leaf XA"));
            comp.Add(new Leaf("Leaf XB"));

            root.Add(comp);

            Composite comp2 = new Composite("Composite XY");
            comp2.Add(new Leaf("Leaf XYA"));
            comp2.Add(new Leaf("Leaf XYB"));

            comp.Add(comp2);

            root.Add(new Leaf("Leaf C"));

            Leaf leaf = new Leaf("Leaf D");
            root.Add(leaf);
            root.Remove(leaf);

            root.Display(1);

            Console.Read();
        }
    }
}
